package ru.incoremedia.gaeutils.dao;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import ru.incoremedia.gaeutils.model.BaseEntity;

public class BaseDao<T extends BaseEntity> {

    protected DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();

    private Class<T> persistentClass;

    public BaseDao() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                    .getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public Key saveOrUpdate(T baseEntity) {
        return datastoreService.put(baseEntity.getEntity());
    }

    public T get(String keyName) {
       return get((Serializable)keyName);
    }

    public T get(long keyId) {
        return get((Serializable)keyId);
    }

    private T get(Serializable nameOrId) {
        try {
            Key key = null;
            
            if(nameOrId instanceof Long) {
                key = KeyFactory.createKey(persistentClass.getName(), (Long)nameOrId);
            } else if(nameOrId instanceof String) {
                key = KeyFactory.createKey(persistentClass.getName(), (String)nameOrId);
            }

            Entity entity = datastoreService.get(key);
            T baseEntity = persistentClass.newInstance();
            baseEntity.setEntity(entity);
            return baseEntity;
        } catch(EntityNotFoundException e) {
            return null;
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
}
